/**
 * Title: jFamilyTree XSLT provider
 * Description: jFamilyTree provider using XSL-transformed GXL file
 * Version: provider
 * Copyright: (c) 2001-2008
 * Terms of use:see license agreement at http://treebolic.sourceforge.net/en/license.htm
 * Author: Bernard Bou
 * Company: bsys
 */
package jFamilyTree.provider.xslt;

import java.io.IOException;
import java.net.URL;

import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;

import org.w3c.dom.Document;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import jFamilyTree.model.Model;
import jFamilyTree.model.Tree;
import jFamilyTree.provider.xml.dom.DocumentAdapter;
import jFamilyTree.provider.xml.dom.Parser;
import bsys.xml.transformer.DomTransformer;

/**
 * Provider with XSL transformation
 * 
 * @author Bernard Bou
 */
public class Provider extends jFamilyTree.provider.xml.dom.Provider
{
	/**
	 * Transformation method
	 */
	static protected final boolean docToDoc = false;

	/**
	 * Get URL of XSLT file
	 * 
	 * @return URL of XSLT file
	 */
	protected URL getXsltUrl()
	{
		String thisXslt = theContext.getParameter("xslt");
		if (thisXslt == null || thisXslt.isEmpty())
			thisXslt = ask("XSLT file:\n");
		if (thisXslt == null || thisXslt.isEmpty())
			return null;
		return theContext.makeURL(thisXslt);
	}

	/**
	 * Get URL of DTD file
	 * 
	 * @return URL of DTD file
	 */
	protected URL getDtdUrl()
	{
		String thisXslt = theContext.getParameter("dtd");
		if (thisXslt == null || thisXslt.isEmpty())
			thisXslt = ask("DTD file:\n");
		if (thisXslt == null || thisXslt.isEmpty())
			return null;
		return theContext.makeURL(thisXslt);
	}

	/**
	 * Get entity resolver
	 */
	protected EntityResolver getEntityResolver()
	{
		return new EntityResolver()
		{
			public InputSource resolveEntity(String thisPublicId, String thisSystemId) throws SAXException, IOException
			{
				URL theDtdUrl = getDtdUrl();
				if (theDtdUrl != null)
				{
					String thisDtd = theDtdUrl.toString();
					thisDtd = thisDtd.substring(thisDtd.lastIndexOf('/'));
					if (thisSystemId.endsWith(thisDtd))
						return new InputSource(theDtdUrl.openStream());
				}
				return null;
			}
		};
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jFamilyTree.provider.xml.dom.Provider#makeModel(java.net.URL)
	 */
	@Override
	protected Model makeModel(URL thisUrl)
	{
		Document thisDocument = makeDocument(thisUrl, getXsltUrl());
		if (thisDocument == null)
			return null;
		return new DocumentAdapter(this).makeModel(thisDocument);
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see jFamilyTree.provider.xml.dom.Provider#makeTree(java.net.URL)
	 */
	@Override
	protected Tree makeTree(URL thisUrl)
	{
		Document thisDocument = makeDocument(thisUrl, getXsltUrl());
		if (thisDocument == null)
			return null;
		return new DocumentAdapter(this).makeTree(thisDocument);
	}

	/**
	 * Make document
	 * 
	 * @param thisUrl
	 *        data url
	 * @param thisXsltUrl
	 *        xslt url
	 * @return document
	 */
	private Document makeDocument(URL thisUrl, URL thisXsltUrl)
	{
		if (docToDoc)
		{
			Document thatDocument = new Parser().makeDocument(thisUrl, getEntityResolver());
			try
			{
				Document thisDocument = new DomTransformer(false, null).documentToDocument(thatDocument, thisXsltUrl);
				return thisDocument;
			}
			catch (TransformerConfigurationException thisException)
			{
			}
			catch (TransformerException thisException)
			{
			}
			catch (IOException thisException)
			{
			}
			return null;
		}
		else
		{
			Document thisDocument = new Parser().makeDocument(thisUrl, thisXsltUrl, getEntityResolver());
			return thisDocument;
		}
	}
}
